#pragma once
#include "ReadInBits.h"
using namespace std;

class CLongReadInBits : public std::pair<CReadInBits, CReadInBits>
{
public:
    CLongReadInBits() { // TODO: double check how to write the default constructor without copy constructor
        CReadInBits r;
        this->first = r;
        this->second = r;
    }
    CLongReadInBits(CReadInBits& first, CReadInBits& second) {
        this->first = first;
        this->second = second;
    }

    CLongReadInBits operator^(const CLongReadInBits &other) const {
        CLongReadInBits r;
        r.first = this->first ^ other.first;
        r.second = this->second ^ other.second;
        return(r);
    }

    inline CLongReadInBits getSuffixStr(unsigned int shift) const {
        CLongReadInBits r;
        r.first = this->first.getSuffixStr(shift);
        r.second = this->second.getSuffixStr(shift);
        return(r);
    }
    inline CLongReadInBits getPrefixStr(unsigned int length) const {
        CLongReadInBits r;
        r.first = this->first.getPrefixStr(length);
        r.second = this->second.getPrefixStr(length);
        return(r);
    }

    inline static bool canBeEncoded(unsigned int readLength) {
        bool properLong = (readLength > (unsigned int)CReadInBits::iReadLength);
        bool properShort = (readLength <= (unsigned int)(2 * CReadInBits::iReadLength));
        return(properLong && properShort);
    }
    inline char* decode(char* caRead, int readlength = 2 * CReadInBits::iReadLength) {
        unsigned int halfOfReadLength = readlength - startOf2ndHalf(readlength);
        decodeRead(caRead, halfOfReadLength, this->first.UpperBits, this->first.LowerBits);
        char* caRead2 = &caRead[startOf2ndHalf(readlength)];
        decodeRead(caRead2, halfOfReadLength, this->second.UpperBits, this->second.LowerBits);
        return(caRead);
    }
};

unsigned int encodeLongRead(const char* read, CReadInBits& firstHalf, CReadInBits& secondHalf);
unsigned int encodeRead(const char* read, CLongReadInBits& r);
CLongReadInBits reverseCompliment(CLongReadInBits r, unsigned int uiReadLength);